package com.gitee.wsl.common.svg

import android.content.Context
import android.graphics.Canvas
import android.graphics.Matrix
import android.graphics.Paint
import android.graphics.Path
import android.graphics.PathMeasure
import android.graphics.Rect
import android.graphics.Region
//import com.caverock.androidsvg.PreserveAspectRatio
//import com.caverock.androidsvg.SVG
//import com.caverock.androidsvg.SVGParseException
//import timber.log.Timber
//
////package com.eftimoff.androipathview;
//
///**
// * Init the SVGUtils with a paint for coloring.
// *
// * @param sourcePaint - the paint for the coloring.
// */
//
//class SvgUtils(
//    /**
//     * The paint provided from the view.
//     */
//    private val mSourcePaint: Paint
//) {
//    /**
//     * All the paths with their attributes from the svg.
//     */
//    private val mPaths: MutableList<SvgPath> = ArrayList()
//
//    /**
//     * The init svg.
//     */
//    private var mSvg: SVG? = null
//
//    /**
//     * Loading the svg from the resources.
//     *
//     * @param context     Context object to get the resources.
//     * @param svgResource int resource id of the svg.
//     */
//    fun load(context: Context?, svgResource: Int) {
//        if (mSvg != null) return
//        try {
//            mSvg = SVG.getFromResource(context, svgResource)
//            mSvg!!.documentPreserveAspectRatio = PreserveAspectRatio.UNSCALED
//        } catch (e: SVGParseException) {
//            Timber.tag(LOG_TAG).e(e, "Could not load specified SVG resource")
//        }
//    }
//
//    /**
//     * Draw the svg to the canvas.
//     *
//     * @param canvas The canvas to be drawn.
//     * @param width  The width of the canvas.
//     * @param height The height of the canvas.
//     */
//    fun drawSvgAfter(canvas: Canvas, width: Int, height: Int) {
//        val strokeWidth = mSourcePaint.strokeWidth
//        rescaleCanvas(width, height, strokeWidth, canvas)
//    }
//
//    /**
//     * Render the svg to canvas and catch all the paths while rendering.
//     *
//     * @param width  - the width to scale down the view to,
//     * @param height - the height to scale down the view to,
//     * @return All the paths from the svg.
//     */
//    fun getPathsForViewport(width: Int, height: Int): List<SvgPath> {
//        val strokeWidth = mSourcePaint.strokeWidth
//        val canvas: Canvas = object : Canvas() {
//            private val mMatrix = Matrix()
//            override fun getWidth(): Int {
//                return width
//            }
//
//            override fun getHeight(): Int {
//                return height
//            }
//
//            override fun drawPath(path: Path, paint: Paint) {
//                val dst = Path()
//                getMatrix(mMatrix)
//                path.transform(mMatrix, dst)
//                paint.isAntiAlias = true
//                paint.style = Paint.Style.STROKE
//                paint.strokeWidth = strokeWidth
//                mPaths.add(SvgPath(dst, paint))
//            }
//        }
//        rescaleCanvas(width, height, strokeWidth, canvas)
//        return mPaths
//    }
//
//    /**
//     * Rescale the canvas with specific width and height.
//     *
//     * @param width       The width of the canvas.
//     * @param height      The height of the canvas.
//     * @param strokeWidth Width of the path to add to scaling.
//     * @param canvas      The canvas to be drawn.
//     */
//    private fun rescaleCanvas(width: Int, height: Int, strokeWidth: Float, canvas: Canvas) {
//        if (mSvg == null) return
//        val viewBox = mSvg!!.documentViewBox
//        val scale = Math.min(
//            width
//                    / (viewBox.width() + strokeWidth),
//            height / (viewBox.height() + strokeWidth)
//        )
//        canvas.translate(
//            (width - viewBox.width() * scale) / 2.0f,
//            (height - viewBox.height() * scale) / 2.0f
//        )
//        canvas.scale(scale, scale)
//        mSvg!!.renderToCanvas(canvas)
//    }
//
//    companion object {
//        /**
//         * It is for logging purposes.
//         */
//        private const val LOG_TAG = "SVGUtils"
//    }
//}

/**
 * Path with bounds for scalling , length and paint.
 */
class SvgPath(
    /**
     * The path itself.
     */
    val path: Path,
    /**
     * The paint to be drawn later.
     */
    val paint: Paint
) {
    /**
     * Listener to notify that an animation step has happened.
     */
    var animationStepListener: AnimationStepListener? = null

    /**
     * The bounds of the path.
     */
    val bounds: Rect

    /**
     * The measure of the path, we can use it later to get segment of it.
     */
    val measure: PathMeasure = PathMeasure(path, false)

    /**
     * The length of the path.
     */
    var length: Float = measure.length
        set(value) {
            field = value
            path.reset()
            measure.getSegment(0.0f, value, path, true)
            path.rLineTo(0.0f, 0.0f)
            if (animationStepListener != null) {
                animationStepListener!!.onAnimationStep()
            }
        }

    /**
     * Constructor to add the path and the paint.
     *
     * @param path  The path that comes from the rendered svg.
     * @param paint The result paint.
     */
    init {
        REGION.setPath(path, MAX_CLIP)
        bounds = REGION.bounds
    }

    companion object {
        /**
         * Region of the path.
         */
        private val REGION = Region()

        /**
         * This is done for clipping the bounds of the path.
         */
        private val MAX_CLIP = Region(Int.MIN_VALUE, Int.MIN_VALUE, Int.MAX_VALUE, Int.MAX_VALUE)
    }
}

interface AnimationStepListener {
    /**
     * Called when an animation step happens.
     */
    fun onAnimationStep()
}